﻿using System;
using System.Globalization;
using System.IO;
using System.Web.Mvc;
using BookShop.BLL;
using BookShop.DTO;
using BookShop.Library.Common;
using BookShop.Library.Constant;
using HTN.Library;
using PagedList;

namespace BookShop.Admin.Controllers
{
    public class BookController : Controller
    {
        public ActionResult Add()
        {
            var mod = (Moderator)Session[SessionKey.Moderator];
            if (mod == null)
            {
                return RedirectToAction("Login", "Home");
            }
            if (!CommonFunction.CheckModeratorRole(mod, ModeratorRole.BookWrite))
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.UnauthorizedAction;
                return RedirectToAction("List");
            }
            return View();
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Add(string title, int categoryId, int authorId, int publisherId, string price,
            string description, string size, int? pageNumber, string publishDate, int quantity)
        {
            var mod = (Moderator)Session[SessionKey.Moderator];
            if (mod == null)
            {
                return RedirectToAction("Login", "Home");
            }
            if (!CommonFunction.CheckModeratorRole(mod, ModeratorRole.BookWrite))
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.UnauthorizedAction;
                return RedirectToAction("List");
            }
            var book = new Book
            {
                Title = title,
                CategoryId = categoryId,
                AuthorId = authorId,
                PublisherId = publisherId,
                CreateTime = DateTime.Now,
                Status = BookStatus.Active,
                AverageRatePoint = 0,
                Description = description,
                Size = size,
                PageNumber = pageNumber,
                UpdateTime = DateTime.Now,
                Quantity = quantity
            };
            DateTime newPublishDate;
            var isValidPublishDate = DateTime.TryParse(publishDate, CultureInfo.CreateSpecificCulture("vi-VN"),
                DateTimeStyles.None, out newPublishDate);
            if (isValidPublishDate)
            {
                book.PublishDate = newPublishDate;
            }
            double newPrice;
            var isValidPrice = double.TryParse(price, NumberStyles.AllowDecimalPoint,
                CultureInfo.CreateSpecificCulture("en-US"), out newPrice);
            if (isValidPrice)
            {
                book.Price = newPrice;
            }
            if (Request.Files.Count > 0)
            {
                var picture = Request.Files["picture"];
                var physicalPath = Path.Combine(CommonFunction.GetConfigValue("UploadPhysicalPath"), "Picture\\Book\\");
                var virtualPath = Utility.UrlCombine("/Upload", "Picture/Book/");
                if (picture != null && !string.IsNullOrWhiteSpace(picture.FileName))
                {
                    var newFileName = Path.GetFileNameWithoutExtension(Utility.UnicodeToKoDau(picture.FileName))
                                      + DateTime.Now.Ticks + Path.GetExtension(picture.FileName);
                    var resultPicture = Utility.UploadFile(picture.InputStream, physicalPath, newFileName, false);
                    if (!resultPicture)
                    {
                        TempData[AlertMessage.TempDataKey] = AlertMessage.FailedToUploadFile;
                    }
                    book.PictureUrl = Utility.UrlCombine(virtualPath, newFileName);
                }
            }
            var addResult = BookService.Add(book);
            if (addResult != null)
            {
                return RedirectToAction("Detail", new { bookId = addResult.Id });
            }
            TempData[AlertMessage.TempDataKey] = AlertMessage.ErrorOccurs;
            ViewBag.AddTitle = title ?? string.Empty;
            ViewBag.AddCategoryId = categoryId;
            ViewBag.AddAuthorId = authorId;
            ViewBag.AddPublisherId = publisherId;
            ViewBag.AddPrice = price ?? string.Empty;
            ViewBag.AddDescription = description ?? string.Empty;
            ViewBag.AddSize = size ?? string.Empty;
            ViewBag.AddPageNumber = pageNumber;
            ViewBag.AddPublishDate = publishDate ?? string.Empty;
            ViewBag.AddQuantity = quantity;
            return View();
        }

        public ActionResult Detail(int bookId)
        {
            var mod = (Moderator)Session[SessionKey.Moderator];
            if (mod == null)
            {
                return RedirectToAction("Login", "Home");
            }
            if (!CommonFunction.CheckModeratorRole(mod, ModeratorRole.BookRead))
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.UnauthorizedAction;
                return RedirectToAction("List");
            }
            var book = BookService.GetById(bookId);
            if (book != null)
            {
                book.AuthorName = (AuthorService.GetById(book.AuthorId) ?? new Author()).Name;
                book.CategoryName = (CategoryService.GetById(book.CategoryId) ?? new Category()).Name;
                book.PublisherName = (PublisherService.GetById(book.PublisherId) ?? new Publisher()).Name;
                return View(book);
            }
            TempData[AlertMessage.TempDataKey] = AlertMessage.NotFoundObject;
            return RedirectToAction("List");
        }

        public ActionResult Edit(int bookId)
        {
            var mod = (Moderator)Session[SessionKey.Moderator];
            if (mod == null)
            {
                return RedirectToAction("Login", "Home");
            }
            if (!CommonFunction.CheckModeratorRole(mod, ModeratorRole.BookWrite))
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.UnauthorizedAction;
                return RedirectToAction("List");
            }
            var book = BookService.GetById(bookId);
            if (book != null)
            {
                return View(book);
            }
            TempData[AlertMessage.TempDataKey] = AlertMessage.NotFoundObject;
            return RedirectToAction("List");
        }

        [HttpPost]
        [ValidateInput(false)]
        public ActionResult Edit(long bookId, string title, int categoryId, int authorId, int publisherId, string price,
            string description, string size, int pageNumber, string publishDate, int quantity, int status)
        {
            var mod = (Moderator)Session[SessionKey.Moderator];
            if (mod == null)
            {
                return RedirectToAction("Login", "Home");
            }
            if (!CommonFunction.CheckModeratorRole(mod, ModeratorRole.BookWrite))
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.UnauthorizedAction;
                return RedirectToAction("List");
            }
            var book = BookService.GetById(bookId);
            if (book == null)
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.NotFoundObject;
                return RedirectToAction("List");
            }
            if (!string.IsNullOrWhiteSpace(title))
            {
                book.Title = title;
            }
            DateTime newPublishDate;
            var isValidPublishDate = DateTime.TryParse(publishDate, CultureInfo.CreateSpecificCulture("vi-VN"),
                DateTimeStyles.None, out newPublishDate);
            if (isValidPublishDate)
            {
                book.PublishDate = newPublishDate;
            }
            double newPrice;
            var isValidPrice = double.TryParse(price, NumberStyles.AllowDecimalPoint,
                CultureInfo.CreateSpecificCulture("en-US"), out newPrice);
            if (isValidPrice)
            {
                book.Price = newPrice;
            }
            book.CategoryId = categoryId;
            book.AuthorId = authorId;
            book.PublisherId = publisherId;
            book.Description = description;
            book.Size = size;
            book.PageNumber = pageNumber;
            book.Quantity = quantity;
            book.Status = status;
            book.UpdateTime = DateTime.Now;
            if (Request.Files.Count > 0)
            {
                var picture = Request.Files["picture"];
                var physicalPath = Path.Combine(CommonFunction.GetConfigValue("UploadPhysicalPath"), "Picture\\Book\\");
                var virtualPath = Utility.UrlCombine("/Upload", "Picture/Book/");
                if (picture != null && !string.IsNullOrWhiteSpace(picture.FileName))
                {
                    var newFileName = Path.GetFileNameWithoutExtension(Utility.UnicodeToKoDau(picture.FileName.Trim(' ').ToLower()))
                                      + DateTime.Now.Ticks + Path.GetExtension(picture.FileName);
                    var resultPicture = Utility.UploadFile(picture.InputStream, physicalPath, newFileName, false);
                    if (!resultPicture)
                    {
                        TempData[AlertMessage.TempDataKey] = AlertMessage.FailedToUploadFile;
                    }
                    book.PictureUrl = Utility.UrlCombine(virtualPath, newFileName);
                }
            }
            var editResult = BookService.Update(book);
            if (editResult != null)
            {
                return RedirectToAction("Detail", new { bookId });
            }
            TempData[AlertMessage.TempDataKey] = AlertMessage.ErrorOccurs;
            return View(book);
        }

        public ActionResult Delete(int bookId)
        {
            var mod = (Moderator)Session[SessionKey.Moderator];
            if (mod == null)
            {
                return RedirectToAction("Login", "Home");
            }
            if (!CommonFunction.CheckModeratorRole(mod, ModeratorRole.BookWrite))
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.UnauthorizedAction;
                return RedirectToAction("List");
            }
            var deleteResult = BookService.Delete(bookId);
            if (!deleteResult)
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.ErrorOccurs;
            }
            return RedirectToAction("List");
        }

        [ValidateInput(false)]
        public ActionResult List(long? bookId, string title, int? categoryId, int? authorId, int? publisherId,
            string fromPrice, string toPrice, int? status, int page = 1, int pageSize = 15)
        {
            var mod = (Moderator)Session[SessionKey.Moderator];
            if (mod == null)
            {
                return RedirectToAction("Login", "Home");
            }
            if (!CommonFunction.CheckModeratorRole(mod, ModeratorRole.BookRead))
            {
                TempData[AlertMessage.TempDataKey] = AlertMessage.UnauthorizedAction;
                return RedirectToAction("Index", "Home");
            }
            int totalRow;
            var model = BookService.Search(bookId, title, categoryId, authorId, publisherId, fromPrice, toPrice, status,
                page, pageSize, out totalRow);
            ViewBag.SearchId = bookId.ToString();
            ViewBag.SearchTitle = title ?? string.Empty;
            ViewBag.SearchCategoryId = categoryId.ToString();
            ViewBag.SearchAuthorId = authorId.ToString();
            ViewBag.SearchPublisherId = publisherId.ToString();
            ViewBag.SearchFromPrice = fromPrice ?? string.Empty;
            ViewBag.SearchToPrice = toPrice ?? string.Empty;
            ViewBag.PageList = new StaticPagedList<Book>(model, page, pageSize, totalRow);
            ViewBag.RecordsCount = "Tổng số bản ghi: " + totalRow;
            return View(model);
        }

        public JsonResult GetAllAuthor()
        {
            return Json(AuthorService.GetAll());
        }

        public JsonResult GetAllCategory()
        {
            return Json(CategoryService.GetAll());
        }

        public JsonResult GetAllPublisher()
        {
            return Json(PublisherService.GetAll());
        }
    }
}
